using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using JobShopModel.Events;
using JobShopModel.Model.Transport;
using JobShopModel.Model.Station;
using JobShopModel.Model.Job;
using JobShopModel.Model.FactoryLvl;

//TODO Comment the class
namespace JobShopModel.Model.FactoryLvl
{
    /// <summary>
    /// Factory, main class of the simulation.
    /// Implement Singleton Design Patern, can only exist one instance of it in the program.
    /// 
    /// </summary>
    class Factory:Observable
    {
        //Instance of factory
        private static Factory myFactory;

        //Curent Time
        private Clock clock;

        private EventQueue eventQueue;

        private List<IStations> listStations;

        private Transporter transporter;

        private FactoryStates status;

        /// <summary>
        /// return instance of the factory if it exits, if not create it.
        /// </summary>
        /// <returns></returns>
        public static Factory getInstance()
        {
            if (myFactory == null)
            {
                myFactory = new Factory();
            }
            return myFactory;
        }


        public Time CurrentTime
        {
            get
            {
                return this.clock.CurrentTime;
            }
            set
            {
                this.clock.increment(value);
            }

        }

        /// <summary>
        /// Default COnstructor
        /// </summary>
        private Factory()
        {
            //Initialize the elements of the class
            initFactory();
        }


        /// <summary>
        /// 
        /// </summary>
        private void initFactory()
        {
            this.clock = new Clock();
            this.eventQueue = new EventQueue();
            this.transporter = new Transporter();
            this.status = FactoryStates.CREATED;
            Time tmp = new Time(0,0.0);
            Time end = new Time(365, 0.0);
            JobShopModel.Extern.Exponential exp = new JobShopModel.Extern.Exponential();
            while (tmp < end)
            {
                tmp.Hours = tmp.Hours + exp.calculate(.25);
                Jobs tmpjob = new Jobs(tmp);
                eventQueue.insertEvent((IEvent)tmpjob);
            }

            /*
             * TODO: Create all the "Create JOB" events randomly distributed
             * following the guideline rule
             * and add them top the QUEUE
             */


        }


        /// <summary>
        /// 
        /// </summary>
        private void simulation()
        {
            //Main loop for the simulation:
            while(status == FactoryStates.RUNNING){
                IEvent evenement = eventQueue.nextEvent();
                evenement.fire();
                Time elapsed = evenement.process();
                


            }


        }




    }
}
